Repository navigation
Conversation
Swap the old "open web research" OG image for one cropped from the homepage banner, saved as a real 1200x630 PNG. The old file was a JPEG at 1376x768, though the metadata declared 1200x630. Drop og-image-twitter.png and point twitter:image at og-image.png. The two files were identical. Add openGraph.images to the home, announcements, privacy, terms and docs pages. Next merges metadata shallowly, so a page that sets its own openGraph without images loses the layout's image.
Once the first token has gone out the status is already 200, so llama.cpp and OpenRouter report a later failure as a `data:` chunk carrying `error`. `_delta()` read that chunk as an empty delta, so the stream closed as if the model had finished: chat stored the cut-off text as a completed reply with no error, and Studio handed it to the JSON parser. Raise `StreamedError` with the endpoint's message instead, so the turn takes the existing mid-reply failure path: an `error` frame, partial text kept.
audio.cpp's joined WAV is encoded in-process by LAME through lameenc, at 64 kbit/s per channel, the model's channels and rate. Without lameenc the episode stays WAV. The frozen worker ships lameenc's dist-info for LAME's LGPL text. Fixes #2001
Collect licence notices for the npm trees, the Python sidecars, the staged native runtimes and the bundled model packs, merge them into THIRD_PARTY_NOTICES.json and .txt, and ship them as resources/notices. The merge fails the build when a dependency has no licence text and the reviewed allowlist gives no reason. Refs #1941
Drop the WebGL dither shader behind the hero headline, along with its styles and the unused CTA dither image. The hero is now a plain server component, leaving the claims tabs and format spotlight as the only client modules on the page.
Turn the full-width nav into a rounded bar inset from the viewport edges and pinned to the top, with a Download button. Phones and tablets get a menu button that opens a separate floating card over a dimmed, blurred page. The announcement banner now scrolls away instead of sticking with the nav.
Replace the ss-home-* classes on every marketing page with Tailwind default utilities. Shared text styles live in siteText, and the FAQ markup repeated across eight pages is now one SiteFaqItem component. home.css shrinks from ~1,840 to ~530 lines. It keeps the marketing palette scoped to .ss-home, so the app's colours stay separate, plus the rules that need real CSS: grid hairlines, tables, menu and FAQ motion, the logo cycle and reduced motion. Those rules sit in the components layer, so utilities override them. Headings now step at breakpoints instead of scaling fluidly.
Swap the cross-fading 4x2 logo grid for a single row that scrolls on a loop, under a pill label on a faded rule. The row fades out at both edges, pauses on hover, holds still for reduced motion, and spaces logos closer on phones. Also thicken the nav surface's rim from 3px to 5px. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pin the canonical light palette inside .ss-home, so marketing pages are light for every visitor while the app stays forced dark. The dark: variant no longer applies inside .ss-home, where it leaked the app's dark styles. Follow-ups for a light ground: - drop prose-invert on blog, changelog, privacy and terms - invert only the light-drawn logos; give the illustrations a shadow - keep the nav icon dark on marketing pages, white elsewhere - soften the nav shadow and draw the spotlight glow from the palette Also narrow the nav to 64rem, drop the Resources panel a little lower, and remove the announcement bar's side rules and the rules around the logo marquee.
The banner above the navbar on every page is gone. The announcement is now a pill above the homepage headline that links to /sunset. It has no dismiss button, so it no longer needs localStorage. NEXT_PUBLIC_TOP_ANNOUNCEMENT_ENABLED keeps its name, so existing deployments keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run the hero full-bleed behind the floating nav over a dithered moonlit scene, and close the page with a matching CTA card on the same image. The image ships as a 3104px WebP master through next/image: AVIF at each screen's width, a priority load for the hero and an inlined blur preview. The CTA reuses the cached file. - add HomeScene, HomeCta and HomeDownloadButton - enable AVIF and allow quality 85 in next.config, since 75 smudges the dither - restyle the announcement pill to read on the photo
- Raise the nav bar to 56px, match its right inset to the logo's, and give it a translucent cool-grey rim that reads on the light page - Add a progressive blur under the bar, stacked in four layers so content softens toward the top edge - Swap the hand-drawn burger for Hugeicons' two-line menu icon, morphing into a cross - Fade the hero scene into the page just below the fold, and pull the hero up by the taller nav's height - Give HomeScene a real `sizes` per use, so phones fetch an image wide enough for the cover crop instead of a blurry 100vw one Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the three illustrated bento cells under "Runs entirely on your machine" with one isometric diorama of the local stack. On large screens the section pins for a screen and each claim (index, model, outputs) lights its objects in blue as you scroll through it; below lg it flows normally and a claim activates as it crosses the viewport. The diorama is generated SVG (generate-air-gap-diorama.mjs writes air-gap-diorama-svg.ts), so it ships with no image request; its active step crossfades via data attributes in home.css. Also add HomeBadge, a pill tuned to the marketing ground, and use it in place of shadcn's secondary Badge on announcements, /free, the model pages, plugins and blog posts. Drop the three old illustration SVGs and HomeArtifactIllustration.
The generator now writes air-gap-diorama.svg instead of a TS string, and the component renders it inline through the existing SVGR loader, dropping dangerouslySetInnerHTML. Step hooks move from classes to data-dio attributes, because SVGR's SVGO prefixes class names inside the SVG; home.css targets the attributes and the wrapper sizes the SVG. The optimised markup is about 25% smaller. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the dark fluted-glass footer with one set on a scene of a castle in the clouds: the download pitch on open ground where the page fades into the sky, and the wordmark, tagline, contact button and link columns on a light card over the hill. The footer now carries the call to action, so the homepage's separate HomeCta card is removed. - add sectionSpacing, one vertical rhythm for the homepage's ruled sections, so every gap between sections is equal and the footer's CTA starts on the same beat - give HomeDownloadButton a dark tone for light ground - move the footer and socials from fixed hex colours to palette tokens
…l every page - Cap each top-level section at --home-max (80rem) instead of the page shell, so content lines up on every route while the hero and footer images run full width (data-bleed opts a section out) - Bring every page onto the same px-6 md:px-10 gutters: uncap MarketingSection and the connector hero, put the MCP pages on the site design, fix doubled gutters on contact and the connector tables, and start long-form columns on the gutter - Centre the FAQ heading like the features section, with a flush option on SiteFaqItem for lists that sit inside the gutters - Mount Lenis once in the site shell for every marketing route, settling it after each navigation so momentum never carries across pages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…20px Above 1920px the root font size grows by 4px for every 640px of width, up to 125% at 2560px. Almost every size on the page is in rem, so the whole page grows together. Screens 1920px wide or less don't change. Also centre the air-gap diorama below the lg breakpoint and give the footer card a bit more vertical padding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every frame of a failed document or analysis script repeated the run folder's absolute path, about 130 characters each, so the 500-character reason the agent reads kept few of the traceback's lines. The folder is deleted once the run ends, so the child now strips it and frames read File "script.py", line N. Removes the matching Known gap from docs/architecture/studio.md.
Rules ran to the 80rem column edge while text sat a gutter in, so dividers, table rules and FAQ rows overshot the text and lists read as wider or narrower than their neighbours. Move the gutter outside the column instead: each section is the column minus a gutter on each side, so its edge is the text edge and every line lands on it. - size `.ss-home-page` sections to `100% - 2 * --home-gutter`; drop the comparison table's first/last-column side padding - remove `px-6 md:px-10` from section heads, text blocks, plain row lists and table wrappers on every marketing page, and the `-mx-6 md:-mx-10` pull-outs around connector tables - keep inner padding only on boxed cells (bento, pillars, plans, feature tabs, card grids) - drop the gutter wrapper from `MarketingSection` and the `flush` prop from `SiteFaqItem`, which every row now matches - drop the duplicate top rule under FAQ and plugin headings - overlay a tiled SVG film grain on the hero scene, kept out of the WebP so it stays sharp when the site scales up - replace the footer scene with a 2:1 summer sky (2 MB -> 150 KB) and re-encode the hero scene (1.1 MB -> 290 KB) - enlarge the trusted-by logos, larger again from md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the flat hairline grid of format cells with rounded cards, each holding a small preview of what that format produces. The bigger formats (podcast, slides, mind map) get large cards on a sky-blue background, and the five written formats share one card of file tiles. Every card lifts on hover. Shorten the format descriptions, rename Summary/Document to Markdown/Word, and drop the FAQ's top border so it doesn't double up with the formats section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Centre the "For confidential work" badge and heading like the Features section, and set the paragraph in a white rounded banner with a dark "Learn more" pill. A cut-out dandelion hill fills the bottom-right corner; it overflows the card so the card clips the image's cropped left edge. Move the section into its own folder and drop the dividers above it and above the formats section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The desktop app runs local models with a bundled llama.cpp and downloads them from huggingface.co only. The homepage, the /free model pages and the privacy page still said Ollama ships in the box and that downloads go to registry.ollama.ai. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ense column Centre the badge and headline like the other sections and set the table in a rounded card, with the SurfSense column raised as a white column. Every cell gets a yes/no/partial mark, judged the same way for every product. On phones a NotebookLM / AnythingLLM / Open Notebook switcher compares SurfSense against one product at a time; the full table stays in the markup for search. Also shorten two cells and drop the dividers above and below the section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each object had its own shadow length, the laptop was shadowed as a solid block as tall as its screen, and grey blobs sat in front of the rack and laptop, opposite the cast shadows. Shadows now come from one undrawn light, half as long as each object is tall, projected from each object's real geometry and faded as one layer so overlaps don't darken. Contact shadows under each footprint replace the offset blobs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The three cells read as steps, not features: index on your disk, your model or key, sources become deliverables. Offline answering now says it needs a local model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Draw the database at 96 sides, curve each disc's drive-bay slot beside its status light, and run both cables under the laptop base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # docs/architecture/documents.md
Docling read every .docx: a 4.6 s torch/transformers import on the first Office file of a worker session, 5 s on a large contract even with the style cache, padded pipe tables, and list numbers that matched Word on only 31% of numbered paragraphs in the reference files (it restarts each list, ignores start overrides and inherited numbering, and writes letters and roman numerals as 1.1.1). A new reader works on the package's XML directly: body paragraphs and tables in order, Docling's heading rules, list numbers rendered as Word shows them (1,876 of 1,876 numbered paragraphs agree with Word's own ListString), compact tables, links, tracked changes as accepted, text boxes once, footnotes and endnotes. The large contract reads in 0.13 s instead of 5.1 s, and a session's first Word file in 0.05 s instead of 4.4 s. Over 791 real DOCX files the text recall against Docling is 1.0 at the median and the 5th percentile. In a clause-question A/B (20 questions, 3 models) it scored 45/60 strict against Docling's 31/60. Docling still reads a file the reader cannot open, one with native charts, and one with no text. Figures come from the figures-only pass, queued at ingest for a file that embeds images. SURFSENSE_LOCAL_DOCX_READER=docling restores Docling.
A page's text layer has line breaks but no blank lines, so the chunker cut long pages at arbitrary lines: on a two-column paper a table's caption and header landed in one passage and its rows in the next. A line now starts a paragraph when the gap above it is more than 1.3 times the wider of its neighbouring line spacings (from pdfium's character origins), captions go with the nearer block, and a lone heading line goes with the block after it. Only newlines are added; the text is otherwise unchanged. Answer evidence in the top 5 passages: Boston budgets 41 -> 44 of 50, a second corpus 20 -> 22 of 23. Answer gates against Docling's markdown: Boston 0.70 vs 0.60 (Gemma 3 4B and Qwen3.5 9B), second corpus 0.83 vs 0.78 with table cells 28/30 vs 27/30 (three models). Gemma lost three Boston table cells, where short paragraphs now pack across a page break. About 0.3 ms a page.
# Conflicts: # surfsense_local/backend/modules/documents/tasks.py # surfsense_local/backend/worker/ingestion/parsing.py
Huey's consumer backs off to polling every 10 s once its queue has been idle for a while. In the packaged app, a worker idle for a minute took 9.6 s to start an upload that its text layer then made ready in about a second. The ingest consumer now polls at least every 0.5 s and the Studio and plugins consumers every second; a poll is one query on huey.db, which is its own file.
…or a deleted source - An asked-for figures pass ran at interactive priority (100), so a Studio draft over many text-read sources queued one pass per source ahead of a note written after it. Asked passes now run at PRIORITY_ASKED (30): behind notes and uploads, ahead of a folder import. - A source deleted while its figures pass read it kept a folder on Windows (the pass held the original open), and SQLite gave the next upload the same id and that folder. The pass now writes only when the same row is still ready with the same original, removes a folder no row owns, and an upload empties its document folder before the file moves in.
…t give way - A PDF whose text layer is refused on some pages (a photo cover, a scanned page, a turned table page) is no longer read whole by Docling: runs of flagged pages are read with page_range and spliced, in page order, with the text-layer pages. Most-flagged files, filled forms and unreadable files are still read whole. Education and Capital Planning (12 pages, photo covers) went from 13.2 s and 28.6 s to 3.5 s and 3.4 s. - A Docling reading longer than one batch reads 8-page batches, checks for cancel between them, and after 60 s gives way to a file or note queued at its own priority or higher, as recordings do; it resumes from a checkpoint stamped with the file's SHA-256, the Docling version and the parser pack. Batched output equals one conversion on a 20-page scan and on Education (markdown, figures.json and PNG bytes). A note written 10 s into a 20-page scan was ready in 61 s instead of 81 s. - The figures-only pass gives way the same way between page runs and resumes; an idle pass gives way to any upload, an asked one only to work at its priority or above. The idle pass is queued for text-read PDFs of at most 40 pages with image objects.
# Conflicts: # docs/architecture/documents.md # surfsense_local/backend/modules/documents/tasks.py # surfsense_local/backend/worker/ingestion/figures/backfill.py
… mixed PDFs and re-measured answers
perf(local): sources usable in seconds: PDF text layer, Word reader without Docling, FP32 embedder on x86-64
The API runs on uvloop on macOS and Linux, whose create_connection has no happy_eyeballs_delay, so every tunnel failed there and opencode never reached a plugin. The option is now passed only on asyncio's own loop, which the API runs on Windows, where it was added. Any failed connect is answered 502 rather than closed unanswered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(local): tunnels through SurfSense's proxy work under uvloop
The 2.2.2 entry for the website's changelog: sources ready in seconds (#2289), speech recognition for recordings and voice input (#2264, #2273), plugin search, permissions, licensing and speed (#2256, #2260, #2261, #2262, #2270, #2291), ChatGPT plan sign-in (#2259), MP3 podcasts (#2183), and the fixes, known issues and developer notes since v2.2.1.
docs(changelog): v2.2.2
2.2.2 makes WAV, MP3, FLAC and Ogg Vorbis recordings sources: transcribed on the machine and answered from with citations. RELEASE.md asks for the format table to match dev before the release merge.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughWarning Review details and warnings were omitted to fit the comment limit. |
Build audio.cpp, which the desktop release needs, had failed on every run since 15 Oct: - Windows: the runner now has Visual Studio 2026, whose vswhere gives its product line as "18" rather than the year, so CMake was asked for the generator "Visual Studio 18 18". The year now comes from the major version when the product line is not a year. - Linux: the recogniser-pin step unpacked the only speech model, and Canary made it two. It now takes Nemotron by its id, the model the gate's tests are written for.
uvloop has no Windows build, so importing it at the top of the module stopped every Windows backend run at collection. Only the uvloop test needs it, and it now skips where uvloop is missing.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Desktop release 2.2.2:
devintomain. The tagv2.2.2goes on this pull request's merge commit (surfsense_local/RELEASE.md).What's in it since 2.2.1 (the full list is in the v2.2.2 changelog entry, #2292):
devsincev2.2.1.Before merging:
dev: Recordings added; the other rows still hold.Build audio.cppfails on PRs since 15 Oct (Windows: the Visual Studio 18 generator; Linux: reading the recogniser's pin). That is not this release's code, but the tag's Desktop Release builds audio.cpp too, so watch it.After merging:
v2.2.2, draft release, then the Known issues from docs(changelog): v2.2.2 #2292 above the generated notes.mainon Coolify: the license server (APP_RELEASE_VERSIONis compiled in, so a redeploy, not a restart), the plugin host and the plugin registry. The website deploys itself on Vercel.